home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / mac / files / amiga / csrc720j.lzh / dir.c < prev    next >
C/C++ Source or Header  |  1993-02-04  |  11KB  |  466 lines

  1. /* dir.c */
  2. #include <libraries/dos.h>
  3. #include <exec/memory.h>
  4. #include "mb.h"
  5. /*
  6.  *  Directory access routines.
  7.  */
  8.  
  9.  
  10. /*
  11.  *  A directory item looks like this:
  12. struct FileInfoBlock {
  13.    LONG fib_DiskKey;
  14.    LONG fib_DirEntryType;
  15.    char fib_FileName[108];
  16.    LONG fib_Protection;
  17.    LONG fib_EntryType;
  18.    LONG fib_Size;
  19.    LONG fib_NumBlocks;
  20.    struct DateStamp fib_Date;
  21.    char fib_Comment[80];
  22.    char padding[36];
  23. };
  24.  */
  25.  
  26. typedef struct FileInfoBlock FCB;
  27. extern char tmpstr[];
  28. extern short debug;
  29. static int olddta;
  30. static FCB *fcb = 0;
  31. static  struct InfoData *ID = 0L;
  32. char wcstring[100];
  33.  
  34. /*
  35.  *  Open directory, return first item.
  36.  */
  37. diropen(cp, p, dirdef)
  38. UBYTE  *cp;
  39. DIRDEF *dirdef;
  40. DIRENT *p;
  41. {
  42.    long  result;
  43.    if(fcb == 0) {
  44.       fcb = (FCB *)AllocMem((long)sizeof(*fcb),
  45.                                    (long)MEMF_PUBLIC|MEMF_CLEAR);
  46.    }
  47.    if(ID == 0) {
  48.       ID = (struct InfoData *)AllocMem((long)sizeof(*ID),
  49.                                    (long)MEMF_PUBLIC|MEMF_CLEAR);
  50.    }
  51.  
  52. /*
  53.  *  Get the first directory entry.
  54.  */
  55.    dirdef->lock = Lock(cp,ACCESS_READ);
  56.    if(dirdef->lock == 0L) {
  57.       p->size = -1;
  58.       return (false);
  59.    }
  60.    if(Info(dirdef->lock,ID) == 0L) {
  61.       /* If Info fails then the named file/device is NOT a disk */
  62.       dirdef->size = 0L;
  63.       dirdef->free = 0L;
  64.       return(false);
  65.    }
  66.    else {
  67.       dirdef->size =
  68.               ((ID->id_BytesPerBlock*ID->id_NumBlocksUsed + 1023L) / 1024L);
  69.       dirdef->free =
  70.               ((ID->id_BytesPerBlock * ID->id_NumBlocks + 1023L) / 1024L)
  71.                   - dirdef->size;
  72.    }
  73.    /* Examine this name to find out what it is - it MUST be a directory */
  74.    if((result = Examine(dirdef->lock,fcb)) == 0L) {
  75.       UnLock(dirdef->lock);
  76.       p->size = -1;
  77.       return (false);
  78.    }
  79.    if(fcb->fib_DirEntryType < 0) {  /* It's a file! That's WRONG! */
  80.       UnLock(dirdef->lock);
  81.       p->size = -1;
  82.       return (false);
  83.    }
  84.    if(dirnext(p,dirdef))return(false);
  85.    if(dodir(p)) return (true);
  86.    return (false);
  87. }
  88. freefcb()
  89. {
  90.    if(fcb)FreeMem(fcb,(long)sizeof(*fcb));
  91.    if(ID)FreeMem(ID,(long)sizeof(*ID));
  92. }
  93. /*
  94.  *  Return first and succeeding filenames in the directory.
  95.  *  And if a wildcard is specified only return the matching
  96.  *  names.
  97.  */
  98.  
  99. dirnext(p, dirdef)
  100. DIRENT *p;
  101. DIRDEF *dirdef;
  102. {
  103.    /* search for next filename in the directory */
  104.    while(true) {
  105.       if(ExNext(dirdef->lock,fcb) == 0L) {
  106.          p->size    = -1;
  107.          UnLock(dirdef->lock);
  108.          return(1);
  109.       }
  110.       if (dodir(p)) {
  111.          return(0);
  112.       }
  113.    }
  114. }
  115.  
  116. dodir(p)
  117. DIRENT *p;
  118. {
  119.    /* wcmatch checks wcstring against fcb->fib_FileName
  120.       If the wildcard is null then everything matches it and
  121.       wcmatch returns a true, otherwise it returns true only
  122.       if the wcstring and filename match
  123.    */
  124.    if(wcmatch(&fcb->fib_FileName[0],&wcstring[0]) == 0)return(false);
  125.    strcpy(p->name,&fcb->fib_FileName[0]);
  126.    if(fcb->fib_DirEntryType >= 0) {  /*It's a directory */
  127.       if(!match(p->name, "/")) {
  128.          return (false);
  129.       }
  130.       if(port->mode & (local | sysop)) {
  131.          strcat(p->name, "/");
  132.       }
  133.       else {
  134.          return (false);
  135.       }
  136.    }
  137.    /* return the size in Kb rounded up */
  138.    p->size = (fcb->fib_Size+01777)>>10;
  139.    return (true);
  140. }
  141.  
  142. /*
  143.  *  Modified form of getdir from original mbfile.c
  144.  *  The amiga searches directories for wildcards in
  145.  *  a different way than does the IBM. SO set it up
  146.  *  for a wildcard match for the amiga.
  147.  *
  148.  */
  149. extern DIRPATH *dphd;
  150. DIRPATH *setdir(p)
  151. char *p;
  152. {
  153.    register DIRPATH *dp;
  154.    register char *cp,*pp;
  155.    cp = p;
  156.    pp = &wcstring[0];
  157.    *pp = 0;
  158.    for(dp = dphd; dp isnt NULL; dp = dp->next)
  159.       if (dp->id is port->opt2)  {
  160.          strcpy(port->line, dp->path);
  161.          while(*cp)*pp++ = *cp++;
  162.          *pp = 0;
  163.          return dp;
  164.       }
  165.    port->msg = mndir;
  166.    return NULL;
  167. }
  168. /* Check filename in *a against a possibly null wildcard string in *b */
  169. wcmatch(a,b)
  170. char *a,*b;
  171. {
  172.    register char *p,*q;
  173.    p = a;
  174.    q = b;
  175.    /* If the wildcard is null then everything matches */
  176.    if(*q == 0)return(1);
  177.    if(*q == '*') {
  178.       /* Leading wildcard * in the pattern */
  179.       while(*p)p++;
  180.       while(*q)q++;
  181.       p--;
  182.       q--;
  183.       while(*q != '*') {
  184.          if(toupper(*p) == toupper(*q)) {
  185.             p--;
  186.             q--;
  187.             continue;
  188.          }
  189.          break;
  190.       }
  191.       if(*q == '*')return(1);
  192.       return(0);
  193.    }
  194.    while(*p && *q && (*q != '*')) {
  195.       if(toupper(*p) == toupper(*q)) {
  196.          p++;
  197.          q++;
  198.          continue;
  199.       }
  200.       break;
  201.    }
  202.    if((*p == 0) && (*q == 0))return(1);
  203.    if(*q == '*')return(1);
  204.    return(0);
  205. }
  206. /* Check call or @bbs in *a against a wildcard string in *b
  207.    Both are ln_call characters long and have trailing spaces added
  208. */
  209.  
  210. wmatch(a,b)
  211. char *a,*b;
  212. {
  213.    register char *p,*q;
  214.    register short i;
  215.    char inname[ln_call+1],wildc[ln_call+1];
  216.  
  217.    /* copy the two input strings into temporary storage, removing the
  218.       trailing blanks. This routine is obviously a slightly modified
  219.       form of the directory wcmatch routine.
  220.       The copy also forces both strings to upper case to save having
  221.       to do it later.
  222.    */
  223.    p = a;
  224.    q = inname;
  225.    for(i = 0;i<ln_call;i++) {
  226.       if(*p == ' ')break;
  227.       *q++ = toupper(*p++);
  228.    }
  229.    *q++ = 0;
  230.    p = b;
  231.    q = wildc;
  232.    for(i = 0;i<ln_call;i++) {
  233.       if(*p == ' ')break;
  234.       *q++ = toupper(*p++);
  235.    }
  236.    *q++ = 0;
  237.    p = inname;
  238.    q = wildc;
  239.    /* If the wildcard is null then everything matches */
  240.    if(*q == 0)return(1);
  241.    if(*q == '*') {
  242.       /* Leading wildcard * in the pattern */
  243.       while(*p)p++;
  244.       while(*q)q++;
  245.       p--;
  246.       q--;
  247.       while(*q != '*') {
  248.          if(*p == *q) {
  249.             p--;
  250.             q--;
  251.             continue;
  252.          }
  253.          break;
  254.       }
  255.       if(*q == '*')return(1);
  256.       return(0);
  257.    }
  258.    while(*p && *q && (*q != '*')) {
  259.       if(*p == *q) {
  260.          p++;
  261.          q++;
  262.          continue;
  263.       }
  264.       break;
  265.    }
  266.    if((*p == 0) && (*q == 0))return(1);
  267.    if(*q == '*')return(1);
  268.    return(0);
  269. }
  270. /* Check title in *a against a quoted string in *b */
  271. /* If the string occurs anywhere in the title then
  272.    return non-null.
  273. */
  274. umatch(a,b)
  275. char *a,*b;
  276. {
  277.    register char *p,*q,*r,*s;
  278.    short i,j;
  279.    if((i = strlen(a)) > 79) {
  280.       i = 79;
  281.       *(a+79) = 0;
  282.    }
  283.    if((j = strlen(b)) > 79) {
  284.       j = 79;
  285.       *(b+79) = 0;
  286.    }
  287.    j -= 2;                 /* Don't count the quotes */
  288.    if(j > i)return(0);     /* Quoted string is longer than title */
  289.    r = a + i - j;
  290.    for(p = a;p <= r;p++) {
  291.       q = p;
  292.       s = b+1;             /* Skip the quote */
  293.       while(*s && (*s != '"')) {
  294.          if(toupper(*q) != *s)break;      /* The string is already upper */
  295.          q++;
  296.          s++;
  297.       }
  298.       if((*s == '"') || (*s == 0))return(1);
  299.    }
  300.    return(0);
  301. }
  302. kill_list()
  303. {
  304.    register int from,to,i;
  305.    register PORTS *p;
  306.    p = port;
  307.    ioport(cport);
  308.    if(!num(port->fld[1]) || !num(port->fld[2])) {
  309.       port->msg = mwhat;
  310.       ioport(p);
  311.       return;
  312.    }
  313.    from = atoi(port->fld[1]);
  314.    to = atoi(port->fld[2]);
  315.    if((from < 1) || (to < 1) || (from >= to)) {
  316.       port->msg = mwhat;
  317.       ioport(p);
  318.       return;
  319.    }
  320.    sprintf(tmpstr,"Delete messages from #%d to #%d\n",from,to);
  321.    outstr(tmpstr);
  322.    if(sure())return;
  323. /* Search forwards through the file to find the first message number
  324.    The messages are more likely to be near the front of the file than
  325.    the end. The end of the file has more recent messages.
  326.    However, a binary search would be the best strategy and I'll put it in
  327.    here when I have time.
  328. */
  329.    check_mail();
  330.    unlock_mail();
  331.    for(i = 1; i <= mfhs->last ; i++)  {
  332.       read_rec(mfl, i, (char *)port->mmhs);
  333. /*
  334. sprintf(tmpstr,"rec#%d = msg#%d\n",i,port->mmhs->number);
  335. ttputs(tmpstr);
  336. */
  337.       if (port->mmhs->number >= from) break;
  338.    }
  339.    if((port->mmhs->number < from) || (port->mmhs->number > to)) {
  340.       outstr("No messages in the specified range\n");
  341.       return;
  342.    }
  343. /* This re-reads the very first record but the loop is easier to
  344.    write this way.
  345.    Delete messages within the specified range.
  346. */
  347.    for( ; i <= mfhs->last ; i++) {
  348.       read_rec(mfl, i, (char *)port->mmhs);
  349.       if (port->mmhs->number > to) break;
  350.  
  351.       /* Is it already dead? */
  352.       if(port->mmhs->stat & m_kill) continue;
  353.  
  354.       /* Don't kill traffic this way. They must be done individually */
  355.       if(port->mmhs->type is 'T')continue;
  356.  
  357.       sprintf(tmpstr,"%d",port->mmhs->number);
  358.       outstr(tmpstr);
  359.       outstr(" - Killed\n");
  360.  
  361.       port->mmhs->stat setbit m_kill;
  362.       write_rec(mfl, i, (char *)port->mmhs);
  363.       makehdr2();
  364.  
  365.    }
  366.    sprintf(tmpstr,"from %d to %d",from,to);
  367.    log('M', 'K', 'L', tmpstr);
  368.    ioport(p);
  369.    port->msg = mdone;
  370.    titles();
  371. }
  372.  
  373.  
  374. char reject[TOT_REJECT][3][ln_call];
  375. short num_reject = 0;
  376.  
  377. get_reject()
  378. {
  379.    /* This routine MUST be called before the window is opened */
  380.    FILE *fp;
  381.    register char *p,*q;
  382.    register int fc,i;
  383.    if((fp = fopen("reject.btn","r")) == NULL)return;
  384.    while(fgets(&tmpstr[0],80,fp) != NULL) {
  385.       p = tmpstr;
  386.       if(*p == '\n')continue;
  387.       fc = 0;
  388.       while(1) {
  389.          switch(*p) {
  390.          case '<':         /* FROM field */
  391.             p++;
  392.             fc++;
  393.             q = &reject[num_reject][2][0];
  394.             pcall(q,p);
  395.             break;
  396.          case '@':         /* AT (BBS) field */
  397.             p++;
  398.             fc++;
  399.             q = &reject[num_reject][1][0];
  400.             pcall(q,p);
  401.             break;
  402.          case '>':         /* TO field */
  403.             p++;
  404.             fc++;
  405.             q = &reject[num_reject][0][0];
  406.             pcall(q,p);
  407.             break;
  408.          }
  409.          while((*p != ' ') && (*p != '\n')  && *p)p++;
  410.          if((*p == '\n') || (*p == 0))break;
  411.          while(*p == ' ')p++;
  412.       }
  413.       if(fc == 0) {    /* No fields found .. don't use it */
  414.          reject[num_reject][0][0] = 0;
  415.          reject[num_reject][1][0] = 0;
  416.          reject[num_reject][2][0] = 0;
  417.          continue;
  418.       }
  419.       if(num_reject++ > TOT_REJECT-1)break;
  420.    }
  421.    fclose(fp);
  422.    if(num_reject > TOT_REJECT-1)num_reject = TOT_REJECT-1;
  423.    printf("\nReject.btn list\n");
  424.    /* This loop does not only prepare the reject list for printing.
  425.       It also converts the fields to upper case. So do not delete
  426.       the entire loop
  427.    */
  428.  
  429.    for(fc = 0;fc < num_reject;fc++) {
  430.       for(i=0;i<3;i++) {
  431.          p = tmpstr;
  432.          *p = 0;
  433.          q = &reject[fc][i][0];
  434.          while(*q && (*q != ' ') && (q < &reject[fc][i][ln_call])) {
  435.             *q = toupper(*q);
  436.             *p++ = *q++;
  437.             *p = 0;
  438.          }
  439.          printf("%c%s ",">@<"[i],&tmpstr[0]);
  440.       }
  441.       printf("\n");
  442.    }
  443.    printf("\n");
  444. }
  445.  
  446. test_reject()
  447. {
  448.    register short i;
  449.    /* Allow sysop to send them out, but reject them from anyone else? */
  450.    /* How about rejecting only when forwarding? */
  451.    if(port->mode == local)return(0);
  452.    for(i=0;i<num_reject;i++) {
  453.       if(reject[i][0][0]) {
  454.          if(!matchn(&reject[i][0][0],port->mmhs->to,ln_call))continue;
  455.       }
  456.       if(reject[i][1][0]) {
  457.          if(!matchn(&reject[i][1][0],port->mmhs->bbs,ln_call))continue;
  458.       }
  459.       if(reject[i][2][0]) {
  460.          if(!matchn(&reject[i][2][0],port->mmhs->from,ln_call))continue;
  461.       }
  462.       return(1);
  463.    }
  464.    return(0);
  465. }
  466.